react 怎么阻止事件冒泡? 您所在的位置:网站首页 react 添加事件 react 怎么阻止事件冒泡?

react 怎么阻止事件冒泡?

2023-03-12 08:41| 来源: 网络整理| 查看: 265

react的事件都是合成事件,所有事件最后都是代理到document上面。(在react17中不再是代理到document,而是react组件树的容器节点)

而你在合成事件内调用e.stopPropagation(),也只能阻止react的合成事件的冒泡触发,不能阻止你在document上绑定的原生事件。

用下面的例子就很容易理解

import React, { useEffect, useRef } from 'react'; export default function Demo() { const appRef = useRef(); const btnRef = useRef(); useEffect(() => { window.addEventListener('click', function () { console.log('window click') }) document.addEventListener('click', function () { console.log('document click') }) btnRef.current.addEventListener('click', function () { console.log('btn click'); }) appRef.current.addEventListener('click', function () { console.log('app click'); }) }, []); function onBtnClick(e) { console.log('react button click'); } function onAppClick(e) { console.log('react app click'); } return ( 按钮 ) }

不添加任何阻止冒泡逻辑的时候,执行顺序如下

btn clickapp clickreact button clickreact app clickdocument clickwindow click

如果我们在按钮的点击事件中添加react阻止冒泡的逻辑

... function onBtnClick(e) { e.stopPropagation(); console.log('react button click'); } ...

可以发现,react合成事件的冒泡被阻止了。所以,react app click没有被打印,但是原生事件没有被阻止,仍然打印

这说明react事件中e.stopPropagation()只能阻止react的合成事件的冒泡。

btn clickapp clickreact button clickdocument click

然后我们换成e.nativeEvent.**stopImmediatePropagation**()

function onBtnClick(e: any) { e.nativeEvent.stopImmediatePropagation() console.log('react button click') }

执行结果如下,可以发现这个api就能达到我们的要求,做到不触发document上的点击事件。

btn clickapp clickreact button clickreact app click

02.stopImmediatePropagation

Event接口的**stopImmediatePropagation()**方法阻止监听同一事件的其他事件监听器被调用。

如果多个事件监听器被附加到相同元素的相同事件类型上,当此事件触发时,它们会按其被添加的顺序被调用。如果在其中一个事件监听器中执行 stopImmediatePropagation() ,那么剩下的事件监听器都不会被调用。

也就是说这个事件会阻止后续添加的事件的执行。

因此当点击事件执行,然后冒泡到document的时候,会阻止document上其他函数的执行。所以达成了我们想要的效果。

03.总结

可以得出以下3种方法在react里阻止事件冒泡

1.通过原生事件阻止事件冒泡,阻止dom原生事件。

btnRef.current.addEventListener('click', function (e) { e.stopPropagation(); console.log('btn click');})

2.使用e.nativeEvent.stopImmediatePropagation()阻止document上同类事件的调用。

function onBtnClick(e) { // e.stopPropagation(); e.nativeEvent.stopImmediatePropagation(); console.log('react button click');}

按钮

3.在window上绑定事件, 因为react16把所有事件都代理到document,window的顺序位于document之后,所以是可以阻止(react jsx事件回调里的e.stopPropagation 只能阻止react 在document上绑定的代理事件的冒泡行为。)

04.实践

第一条不实用,相当于我们在react里面,不用react的合成事件,而增加了原生代码的比例。

第三条实际上没有阻止到document上点击事件的触发,

因此还是用stopImmediatePropagation+stopPropagation的方式,这样能阻止react合成事件冒泡,又能阻止document上事件的执行。

因此最后可以编写下面的通用函数来阻止冒泡

import { SyntheticEvent } from 'react' /** * 取消事件冒泡 * @param e */ export default function cancelBubble(e: SyntheticEvent) { e.stopPropagation() e.nativeEvent.stopImmediatePropagation() }



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有